package cn.siriusbot.siriuspro.bot.api.impl.bot;

import cn.siriusbot.siriuspro.admin.dao.AppConfigMapper;
import cn.siriusbot.siriuspro.admin.dao.PluginsMapper;
import cn.siriusbot.siriuspro.admin.entity.AppConfig;
import cn.siriusbot.siriuspro.admin.entity.Plugins;
import cn.siriusbot.siriuspro.bot.api.ConfigApi;
import cn.siriusbot.siriuspro.bot.application.SiriusApplicationInfo;
import cn.siriusbot.siriuspro.error.MsgException;
import lombok.Data;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;

@Log4j2
@Component
@Data
public class ConfigApiImpl implements ConfigApi {

    @Autowired
    PluginsMapper pluginsMapper;

    @Autowired
    AppConfigMapper appConfigMapper;

    String packageName;

    Plugins plugins;


    public ConfigApi build(SiriusApplicationInfo info) {
        ConfigApiImpl configApi = new ConfigApiImpl();
        BeanUtils.copyProperties(this, configApi);
        configApi.packageName = info.getPackageName();
        configApi.plugins = pluginsMapper.queryByPackageName(info.getPackageName());
        if (configApi.plugins == null) {
            configApi.plugins = new Plugins(info);
            pluginsMapper.insert(configApi.plugins);
            configApi.plugins = pluginsMapper.queryByPackageName(info.getPackageName());
        }
        return configApi;
    }

    /**
     * 读配置项
     *
     * @param database   数据库名(->易语言中的文件名)
     * @param node       节点名
     * @param config     配置项名
     * @param defaultVal 如果为空时默认值
     * @return 读取结果
     */
    @Override
    public String readConfig(String database, String node, String config, String defaultVal) {
        AppConfig appConfig = appConfigMapper.queryOne(plugins.getId(), database, node, config);
        if (appConfig == null) {
            return defaultVal;
        }
        return appConfig.getValue();
    }

    /**
     * 写配置项
     *
     * @param database 数据库名(->易语言中的文件名)
     * @param node     节点名
     * @param config   配置项名
     * @param value    写入值
     */
    @Override
    @Transactional
    public void writeConfig(String database, String node, String config, String value) {
        if (ObjectUtils.isEmpty(database)) {
            throw new MsgException(500, "数据库名不能为空!");
        }
        if (ObjectUtils.isEmpty(node)) {
            throw new MsgException(500, "节点名不能为空");
        }
        if (ObjectUtils.isEmpty(config)) {
            throw new MsgException(500, "配置项名不能为空!");
        }
        if (value == null) {
            throw new MsgException(500, "写入值不能为空!");
        }
        AppConfig appConfig = appConfigMapper.queryOne(plugins.getId(), database, node, config);
        if (appConfig == null) {
            appConfig = new AppConfig()
                    .setPluginsId(plugins.getId())
                    .setDatabase(database)
                    .setNode(node)
                    .setConfig(config)
                    .setValue(value);
            appConfigMapper.insert(appConfig);
            return;
        }
        appConfig.setValue(value);
        appConfigMapper.updateById(appConfig);
    }

    /**
     * 获取数据库下的节名列表
     *
     * @param database 数据库名(->易语言中的文件名)
     * @return 节名列表对象
     */
    @Override
    public List<String> getNodeList(String database) {
        List<AppConfig> nodeList = appConfigMapper.getNodeList(plugins.getId(), database);
        List<String> result = new ArrayList<>();
        nodeList.forEach(item -> result.add(item.getNode()));
        return result;
    }

    /**
     * 获取节名下的配置项名列表
     *
     * @param database 数据库名(->易语言中的文件名)
     * @param node     节名
     * @return 配置项名列表
     */
    @Override
    public List<String> getConfigList(String database, String node) {
        List<AppConfig> configList = appConfigMapper.getConfigList(plugins.getId(), database, node);
        List<String> result = new ArrayList<>();
        configList.forEach(item -> result.add(item.getConfig()));
        return result;
    }

    /**
     * 获取数据库列表
     *
     * @return 数据库名列表
     */
    @Override
    public List<String> getDataBaseList() {
        List<AppConfig> configList = appConfigMapper.getDatabaseList(plugins.getId());
        List<String> result = new ArrayList<>();
        configList.forEach(item -> result.add(item.getConfig()));
        return result;
    }

    /**
     * 删除数据库
     *
     * @param database 数据库名(->易语言中的文件名)
     */
    @Override
    public void delDatabase(String database) {
        appConfigMapper.delDatabase(plugins.getId(), database);
    }

    /**
     * 删除节名
     *
     * @param database 数据库名(->易语言中的文件名)
     * @param node     节名
     */
    @Override
    public void delNode(String database, String node) {
        appConfigMapper.delNode(plugins.getId(), database, node);
    }

    /**
     * 删除配置项
     *
     * @param database 数据库名(->易语言中的文件名)
     * @param node     节名
     * @param config   配置项名
     */
    @Override
    public void delConfig(String database, String node, String config) {
        appConfigMapper.delConfig(plugins.getId(), database, node, config);
    }
}
